package com.hoshiibuy.sys.permission.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hoshiibuy.common.aop.Logable;
import com.hoshiibuy.common.rpc.Response;
import com.hoshiibuy.sys.permission.dao.SysOrganizationMapper;
import com.hoshiibuy.sys.permission.dao.SysPermissionesMapper;
import com.hoshiibuy.sys.permission.dao.SysRolePermissionesMapper;
import com.hoshiibuy.sys.permission.dao.SysRolesMapper;
import com.hoshiibuy.sys.permission.dao.SysUserRoleMapper;
import com.hoshiibuy.sys.permission.dao.SysUsersMapper;
import com.hoshiibuy.sys.permission.entity.SysOrganization;
import com.hoshiibuy.sys.permission.entity.SysPermissiones;
import com.hoshiibuy.sys.permission.entity.SysRolePermissiones;
import com.hoshiibuy.sys.permission.entity.SysRoles;
import com.hoshiibuy.sys.permission.entity.SysUserRole;
import com.hoshiibuy.sys.permission.entity.SysUsers;
import com.hoshiibuy.sys.permission.entity.param.RObject;
import com.hoshiibuy.sys.permission.feign.IdGeneratorRemote;
import com.hoshiibuy.sys.permission.feign.Neo4jRemote;
import com.hoshiibuy.sys.permission.service.ISysUsersService;

/**
 * TODO 事务，缓存，异常控制
 * 
 * @Description: 用户服务实现类
 * @author Mr.wu
 * @date: 2019年4月22日 下午6:13:43
 */
@Service
public class SysUsersServiceImpl extends ServiceImpl<SysUsersMapper, SysUsers> implements ISysUsersService {

	@Autowired
	private SysUsersMapper sysUsersMapper;

	@Autowired
	private SysPermissionesMapper sysPermissionesMapper;

	@Autowired
	private SysRolePermissionesMapper sysRolePermissionesMapper;

	@Autowired
	private SysUserRoleMapper sysUserRoleMapper;

	@Autowired
	private SysOrganizationMapper sysOrganizationMapper;

	@Autowired
	private SysRolesMapper sysRolesMapper;

	@Autowired
	private Neo4jRemote neo4jRemote;

	@Autowired
	private IdGeneratorRemote idGeneratorRemote;

	@Override
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(cacheNames = { "sysUser", "sysUserRole" }, allEntries = true)
	@Logable(authName = "权限相关-用户信息管理-新增用户信息")
	public Response addSysUser(SysUsers param) {
		int count = 0;
		// TODO 判断部门ID是否合法

		// 判断部门是否存在
		SysOrganization dept = sysOrganizationMapper.selectById(param.getDeptid());
		if (dept == null) {
			throw new ServiceException("部门不存在");
		}
		String id = idGeneratorRemote.getId();
		if (StringUtils.isBlank(id)) {
			throw new ServiceException("id服务失败");
		}
		param.setId(Long.valueOf(id));
		param.setCreatedtime(LocalDateTime.now());
		count = sysUsersMapper.insert(param);
		if (count == 0) {
			throw new ServiceException("新增失败");
		}
		// 根据角色ID创建用户权限
		List<String> roleIdList = param.getRoleIdList();
		if (roleIdList != null && roleIdList.size() > 0) {
			// 查询id列表是否合规
			QueryWrapper<SysRoles> queryWrapper = new QueryWrapper<SysRoles>();
			// TODO 添加关联ID和分类查询
			queryWrapper.in("id", roleIdList);
			count = sysRolesMapper.selectCount(queryWrapper);
			if (count != roleIdList.size()) {
				// 根据id列表查询到的可用角色不匹配，返回错误
				throw new ServiceException("可用角色数量不匹配，请刷新重试");
			}
			// 创建用户和角色的关联
			for (String roleId : roleIdList) {
				SysUserRole entity = new SysUserRole();
				entity.setId(IdWorker.getId());
				entity.setRoleId(Long.valueOf(roleId));
				entity.setUserId(param.getId());
				sysUserRoleMapper.insert(entity);
			}
		}

		// 插入neo4j节点
		RObject neo4jParam = new RObject();
		// 用户所属部门名称
		neo4jParam.setLabel(dept.getName());
		neo4jParam.setUuid(id);
		neo4jParam.addProperty("uuid", id);
		neo4jParam.addProperty("name", param.getRealname());
		Response result = neo4jRemote.addRole(neo4jParam);
		if (result != null && !result.isSuccess()) {
			throw new ServiceException("neo4j服务失败," + result.getMsg());
		} else if (result == null) {
			throw new ServiceException("neo4j服务失败");
		}

		return Response.success("新增成功");
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(cacheNames = { "sysUser", "sysUserRole" }, allEntries = true)
	@Logable(authName = "权限相关-用户信息管理-修改用户信息")
	public Response updateSysUser(SysUsers param) {
		int count = 0;
		// 根据角色ID创建用户权限
		List<String> roleIdList = param.getRoleIdList();
		if (roleIdList != null && roleIdList.size() > 0) {
			// 查询id列表是否合规
			QueryWrapper<SysRoles> queryWrapper = new QueryWrapper<SysRoles>();
			// TODO 添加关联ID和分类查询
			queryWrapper.in("id", roleIdList);
			count = sysRolesMapper.selectCount(queryWrapper);
			if (count != roleIdList.size()) {
				// 根据id列表查询到的可用角色不匹配，返回错误
				throw new ServiceException("可用角色数量不匹配，请刷新重试");
			}
			// 先删除关联角色
			QueryWrapper<SysUserRole> deleteWrapper = new QueryWrapper<SysUserRole>();
			deleteWrapper.eq("user_id", param.getId());
			sysUserRoleMapper.delete(deleteWrapper);

			// 新增新的关联角色
			// 创建用户和角色的关联
			for (String roleId : roleIdList) {
				SysUserRole entity = new SysUserRole();
				entity.setId(IdWorker.getId());
				entity.setRoleId(Long.valueOf(roleId));
				entity.setUserId(param.getId());
				sysUserRoleMapper.insert(entity);
			}

		}
		sysUsersMapper.updateById(param);
		return Response.success("修改成功");
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(cacheNames = { "sysUser", "sysUserRole" }, allEntries = true)
	@Logable(authName = "权限相关-用户信息管理-删除用户信息")
	public Response deleteSysUser(Long id) {
		// 先删除关联角色
		QueryWrapper<SysUserRole> deleteWrapper = new QueryWrapper<SysUserRole>();
		deleteWrapper.eq("user_id", id);
		int count = 0;
		count = sysUserRoleMapper.delete(deleteWrapper);
		if (count == 0) {
			throw new ServiceException("删除失败");
		}
		// 删除用户数据
		count = sysUsersMapper.deleteById(id);
		if (count == 0) {
			throw new ServiceException("删除失败");
		}
		return Response.success("删除成功");
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#id")
	@Logable(authName = "权限相关-用户信息管理-查询用户信息详情")
	public Response getSysUserDetail(Long id) {
		SysUsers sysUsers = sysUsersMapper.selectById(id);
		if (sysUsers == null) {
			return Response.failed("数据不存在");
		}
		return Response.data(sysUsers);
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#id")
	@Logable(authName = "权限相关-用户信息管理-查询用户权限列表")
	public Response<List<String>> getSysUserPermissionList(Long id) {
		// 获取系统用户关联的角色列表
		QueryWrapper<SysUserRole> queryWrapper_userRole = new QueryWrapper<SysUserRole>();
		List<SysUserRole> roleList = sysUserRoleMapper.selectList(queryWrapper_userRole);

		List<Long> roleIdList = new ArrayList<Long>();
		for (SysUserRole sysUserRole : roleList) {
			roleIdList.add(sysUserRole.getRoleId());
		}

		QueryWrapper<SysRolePermissiones> queryWrapper_rolePer = new QueryWrapper<SysRolePermissiones>();
		queryWrapper_rolePer.in("role_id", roleIdList);
		List<SysRolePermissiones> rolePermissionesList = sysRolePermissionesMapper.selectList(queryWrapper_rolePer);

		// 根据角色ID列表组装权限ID列表
		List<Long> permissionIdList = new ArrayList<Long>();
		for (SysRolePermissiones sysRolePermissiones : rolePermissionesList) {
			permissionIdList.add(sysRolePermissiones.getPermissionId());
		}
		// 根据权限ID列表取得权限值列表
		List<SysPermissiones> permissionesList = sysPermissionesMapper.selectBatchIds(permissionIdList);

		// TODO 预留的权限状态检查
		if (permissionIdList.size() != permissionesList.size()) {
			throw new ServiceException("角色权限跟可用权限不匹配");
		}
		List<String> permissionValueList = new ArrayList<String>();
		for (SysPermissiones sysPermissiones : permissionesList) {
			permissionValueList.add(sysPermissiones.getPermissionValue());
		}
		return Response.data(permissionValueList);
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "T(com.hoshiibuy.common.utils.DigestUtils).md5(Wrapper(SqlSelect=' + #queryWrapper.getSqlSelect() + ', SqlSegment=' + #queryWrapper.getSqlSegment() + ')')")
	@Logable(authName = "权限相关-用户信息管理-查询用户信息列表")
	public Response getSysUserList(QueryWrapper<SysUsers> queryWrapper) {
		// TODO Auto-generated method stub
		List<SysUsers> list = sysUsersMapper.selectList(queryWrapper);
		return Response.data(list);
	}

	@Override
	@Cacheable(cacheNames = "sysUser", key = "T(com.hoshiibuy.common.utils.DigestUtils).md5('Page(current=' + #page.getCurrent() + ', size=' + #page.getSize() + '), Wrapper(SqlSelect=' + #queryWrapper.getSqlSelect() + ', SqlSegment=' + #queryWrapper.getSqlSegment() + ')')")
	@Logable(authName = "权限相关-用户信息管理-分页查询用户信息")
	public Response getPage(IPage<SysUsers> page, QueryWrapper<SysUsers> queryWrapper) {
		return Response.data(sysUsersMapper.selectPage(page, queryWrapper));
	}

}
